package club.monkeywood.controller.wechat;

import club.monkeywood.config.wechat.CookieConfig;
import club.monkeywood.config.wechat.WechatConfig;
import club.monkeywood.dataobject.Buyer;
import club.monkeywood.dto.wechat.token.AccessTokenByCode;
import club.monkeywood.dto.wechat.user.UserInfo;
import club.monkeywood.enums.wechat.wxMessageEnum;
import club.monkeywood.dto.wechat.token.AccessToken;
import club.monkeywood.service.buyer.BuyerService;
import club.monkeywood.util.cookie.CookieUtil;
import club.monkeywood.util.wechat.CheckUtil;
import club.monkeywood.util.wechat.MessageUtil;
import club.monkeywood.util.wechat.WechatUtil;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;



@RestController
@RequestMapping("/wechat")
@Slf4j
public class WechatController {

    @Autowired
    private CookieConfig cookieConfig;

    @Autowired
    private WechatUtil wechatUtil;

    @Autowired
    private BuyerService buyerService;

    @GetMapping("/hello")
    public String hello() {
        return "hello wechat";
    }

//    接口配置信息修改服务
    @GetMapping("/signatureandmessage")
    public String signature(@RequestParam("signature") String signature,
                        @RequestParam("timestamp") String timestamp,
                        @RequestParam("nonce") String nonce,
                        @RequestParam("echostr") String echostr) {
        if(CheckUtil.checkSignature(signature,timestamp,nonce))
            return echostr;
        else
            return "error";
    }

//    自定义菜单、消息响应服务
    @PostMapping("/signatureandmessage")
    public String message(HttpServletRequest request){
        try{
//            从xml中解析出字段值
            Map<String,String> map = MessageUtil.xmlToMap(request);
            String fromUserName =map.get("FromUserName");
            String toUserName = map.get("ToUserName");
            String msgType = map.get("MsgType");
            String content = map.get("Content");

            String message = null;
            //WechatUtil.Init(wechatConfig);
            // 用户文本消息回复
            if(wxMessageEnum.MESSAGE_TEXT.getType().equals(msgType)){
                //创建菜单
                if("createmenu".equals(content)){
                    AccessToken accessToken = wechatUtil.getAccessToken();
                    wechatUtil.createMenu(accessToken.getAccess_token());
                    message = MessageUtil.initText(toUserName,fromUserName,"创建菜单成功！");
                }
                //查询菜单
                else if("querymenu".equals(content)) {
                    AccessToken accessToken = wechatUtil.getAccessToken();
                    wechatUtil.queryMenu(accessToken.getAccess_token());
                    message = MessageUtil.initText(toUserName,fromUserName,"查询菜单成功！");
                }
                //删除菜单
                else if("deletemenu".equals(content)) {
                    AccessToken accessToken = wechatUtil.getAccessToken();
                    wechatUtil.deleteMenu(accessToken.getAccess_token());
                    message = MessageUtil.initText(toUserName,fromUserName,"删除菜单成功！");
                }

//          事件消息回复
//          事件包括：
//          1)自定义菜单
//          2)关注、取关
            }else if(wxMessageEnum.MESSAGE_EVENT.getType().equals(msgType)){
                String eventType = map.get("Event");
//                关注事件
                if(wxMessageEnum.EVENT_SUBSCRIBE.getType().equals(eventType)){
                    message = MessageUtil.initText(toUserName,fromUserName,"谢谢关注！");
                }
//                点击click菜单事件
                else if(wxMessageEnum.EVENT_CLICK.getType().equals(eventType)){
                    //WechatUtil.Init(wechatConfig);
                    String token = wechatUtil.getAccessToken().getAccess_token();
//                    String ret = "查询菜单:" + WechatUtil.queryMenu(token);
                    String ret = "删除菜单:";
                    wechatUtil.deleteMenu(token);
                    message = MessageUtil.initText(toUserName,fromUserName,ret);
                }
//                点击view菜单事件
                else if(wxMessageEnum.EVENT_VIEW.getType().equals(eventType)){
                    String retStr = "点击view菜单事件";
                    String url = map.get("EventKey");
                    retStr += "url:" + url;
                    message = MessageUtil.initText(toUserName,fromUserName,retStr);
                }
//                点击扫码菜单事件
                else if(wxMessageEnum.EVENT_SCANCODE_PUSH.getType().equals(eventType)){
                    String retStr = "点击扫码菜单事件";
                    String EventKey = map.get("EventKey");
                    retStr += "EventKey:" + EventKey;
                    message = MessageUtil.initText(toUserName,fromUserName,retStr);
                }
            }

            return message;
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return "";
    }

    //获取微信用户信息服务
    //url:/wechat/getuserinfo?returnurl=/
    //returnurl:获取微信用户信息前的回调url，获取用户信息成功后，跳转回returnurl地址
    //spring boot自动urldecode解码returnurl
    @GetMapping("/getuserinfostepone")
    public void getUserInfoStepOne(@RequestParam("returnurl") String returnUrl,
                                     HttpServletResponse response) throws IOException {
        //1. 装配“用户同意授权，获取code”微信官服url
        //WechatUtil.Init(wechatConfig);
        String redirectUrl = wechatUtil.buildAuthorizationUrl(wechatUtil.getSNSAPI_BASE(),
                                wechatUtil.getWechatConfig().getProjecturl().get("AUTHORIZE_URL"),
                                                              returnUrl);

        //2. 跳转到“用户同意授权，获取code”微信官服url
        //微信官服验证合法后，将code发给回调地址：
        //“用户同意授权，获取code”微信官服url中的redirect参数的url地址
        //也就是：/wechat/getuserinfosteptwo
        response.sendRedirect(redirectUrl);
    }

    //“用户同意授权，获取code”微信官服url的回调地址
    // 用户同意授权后，获取code
    // 获取网页授权后的二跳地址
    //code:微信官服传入，通过code换取access_token的票据
    @GetMapping("/getuserinfosteptwo")
    public void getUserInfoStepTwo(@RequestParam("code") String code, @RequestParam("state") String returnUrl,
                                   HttpSession session,
                                   HttpServletResponse response) throws IOException {

        //通过code换取网页授权access_token
        AccessTokenByCode token =wechatUtil.getAccessTokenByCode(code);

        //拉取用户信息(需scope为 snsapi_userinfo)
        UserInfo userInfo = wechatUtil.getUserInfoByAccessToken(token.getAccess_token(),token.getOpenid());

        Buyer buyerdb = buyerService.findByOpenid(userInfo.getOpenid());
        Buyer buyerwx = new Buyer();
        buyerwx.setName(userInfo.getNickname());
        buyerwx.setOpenid(userInfo.getOpenid());
        buyerwx.setAvatar(userInfo.getHeadimgurl());
        buyerwx.setSex(userInfo.getSex());
        buyerwx.setProvince(userInfo.getProvince());
        buyerwx.setCity(userInfo.getCity());
        buyerwx.setCountry(userInfo.getCountry());
        buyerwx.setPrivilege(userInfo.getPrivilege().toString());
        buyerwx.setUnionid(userInfo.getUnionid());
        if(buyerdb == null) {
            buyerwx = buyerService.save(buyerwx);
            session.setAttribute("user" , buyerwx);
        }else if(buyerdb.equals(buyerwx)){
            buyerwx = buyerService.save(buyerwx);
            session.setAttribute("user" , buyerwx);
        }

        //重定向到回调url
        if(returnUrl.indexOf("?")>0) {
            returnUrl = returnUrl + "&openid="+buyerwx.getOpenid();
        }else{
            returnUrl = returnUrl + "?openid="+buyerwx.getOpenid();
        }

        response.sendRedirect(returnUrl);
    }

}
